package com.example.my_tool_2;

import static androidx.constraintlayout.helper.widget.MotionEffect.TAG;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.SystemClock;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {
    Context context;
    SharedPreferences config;
    SharedPreferences.Editor editor;
    Main main = null;

    TextView tv_connect;
    TextView tv_ping;
    EditText et_ip;
    EditText et_port;

    TextView tv_data_match;

    Button btn_1;
    Button btn_2;
    Button btn_3;
    Button btn_4;
    Button btn_5;
    Button btn_6;
    Button btn_7;
    Button btn_8;
    Button btn_9;
    Button btn_10;
    Button btn_11;
    Button btn_0;

    boolean send_data_flag=false;

    Socket socket;
    int socket_flag = 0;
    int timeout;
    boolean Main_Runnable_flag = false;
    int Main_Runnable_count = 0;
    static class ping_data{
        ping_data( byte Data,long Dime){
            data = Data;
            time = Dime;
        }
        public byte data;
        public long time;
    }
    List<ping_data> ping_data_list = new ArrayList<>();

    @SuppressLint("DiscouragedApi")
    void Init()
    {
        context = this;
        config = this.getSharedPreferences("config", MODE_PRIVATE);
        editor = config.edit();
        if (main == null)main=new Main(config,editor);

        tv_connect = findViewById(R.id.tv_connect);
        tv_connect.setText(main.tv_connect_text);
        tv_connect.setGravity(Gravity.CENTER);
        tv_connect.setTypeface(Typeface.DEFAULT_BOLD);
        tv_connect.setTextColor(ContextCompat.getColor(this, main.tv_connect_text_color));
        tv_connect.setShadowLayer(5, 5, 5, ContextCompat.getColor(this, main.tv_connect_text_Shadow_color));

        tv_ping = findViewById(R.id.tv_ping);
        tv_ping.setText(main.tv_ping_text);
        tv_ping.setTextColor(ContextCompat.getColor(this, main.tv_ping_text_color));
        tv_ping.setShadowLayer(5, 5, 5, ContextCompat.getColor(this, main.tv_ping_text_Shadow_color));

        et_ip = findViewById(R.id.et_ip);
        et_ip.setText(main.et_ip_text);
        et_ip.addTextChangedListener(new TextWatcher() {
            @SuppressLint("SetTextI18n")
            public void onTextChanged(CharSequence s, int start, int before, int count) {}
            public void afterTextChanged(Editable s) {
                String input = s.toString();
                if (!isValidIpAddress(input)) {
                    et_ip.setError("IP地址格式错误");
                }
                else {
                    main.et_ip_text = et_ip.getText().toString();
                    editor.putString("et_ip_text", main.et_ip_text);
                    editor.apply();
                }
            }
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
            private boolean isValidIpAddress(String ip) {
                String ipPattern =// 正则表达式检查IP地址
                        "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}" +
                                "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";
                return ip.matches(ipPattern);
            }
        });

        et_port = findViewById(R.id.et_port);
        et_port.setText(main.et_port_text);
        et_port.addTextChangedListener(new TextWatcher() {
            @SuppressLint("SetTextI18n")
            public void onTextChanged(CharSequence s, int start, int before, int count) {}
            public void afterTextChanged(Editable s) {
                String input = s.toString();
                if (!isValidPort(input)) {
                    et_port.setError("端口格式错误");
                }
                else {
                    main.et_port_text = et_port.getText().toString();
                    editor.putString("et_port_text", main.et_port_text);
                    editor.apply();
                }
            }
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
            private boolean isValidPort(String ip) {
                if (!ip.isEmpty()) {
                    int input = Integer.parseInt(ip);
                    return input >= 0 && input <= 65535;
                }
                return false;
            }
        });


        tv_data_match = findViewById(R.id.tv_data_match);
        tv_data_match.setShadowLayer(5, 5, 5, ContextCompat.getColor(this, main.tv_data_match_text_Shadow_color));


        btn_0 = findViewById(R.id.btn_0);btn_0.setBackgroundColor(ContextCompat.getColor(context, R.color.midnightblue));
        btn_1 = findViewById(R.id.btn_1);btn_1.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
        btn_2 = findViewById(R.id.btn_2);btn_2.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
        btn_3 = findViewById(R.id.btn_3);btn_3.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
        btn_4 = findViewById(R.id.btn_4);btn_4.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
        btn_5 = findViewById(R.id.btn_5);btn_5.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
        btn_6 = findViewById(R.id.btn_6);btn_6.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
        btn_7 = findViewById(R.id.btn_7);btn_7.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
        btn_8 = findViewById(R.id.btn_8);btn_8.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
        btn_9 = findViewById(R.id.btn_9);btn_9.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
        btn_10 = findViewById(R.id.btn_10);btn_10.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
        btn_11 = findViewById(R.id.btn_11);btn_11.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));

        switch (main.car_sign[0]) {
            case 1:btn_1.setBackgroundColor(ContextCompat.getColor(context, R.color.red));break;
            case 2:btn_2.setBackgroundColor(ContextCompat.getColor(context, R.color.red));break;
            case 3:btn_3.setBackgroundColor(ContextCompat.getColor(context, R.color.red));break;
        }
        switch (main.car_sign[1]) {
            case 1:btn_4.setBackgroundColor(ContextCompat.getColor(context, R.color.red));break;
            case 2:btn_5.setBackgroundColor(ContextCompat.getColor(context, R.color.red));break;
            case 3:btn_6.setBackgroundColor(ContextCompat.getColor(context, R.color.red));break;
        }
        switch (main.car_sign[2]) {
            case 1:btn_7.setBackgroundColor(ContextCompat.getColor(context, R.color.red));break;
            case 2:btn_8.setBackgroundColor(ContextCompat.getColor(context, R.color.red));break;
            case 3:btn_9.setBackgroundColor(ContextCompat.getColor(context, R.color.red));break;
        }
        switch (main.work_sign) {
            case 1:btn_10.setBackgroundColor(ContextCompat.getColor(context, R.color.red));break;
            case 2:btn_11.setBackgroundColor(ContextCompat.getColor(context, R.color.red));break;
        }
        btn_1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (main.car_sign[0]!=1){
                    main.car_sign[0]=1;
                    btn_1.setBackgroundColor(ContextCompat.getColor(context, R.color.red));
                    btn_2.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_3.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                }
                else {
                    main.car_sign[0]=0;
                    btn_1.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_2.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_3.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                }
                editor.putInt("car_sign0", main.car_sign[0]);
                editor.apply();
            }
        });
        btn_2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (main.car_sign[0]!=2){
                    main.car_sign[0]=2;
                    btn_1.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_2.setBackgroundColor(ContextCompat.getColor(context, R.color.red));
                    btn_3.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                }
                else {
                    main.car_sign[0]=0;
                    btn_1.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_2.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_3.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                }
                editor.putInt("car_sign0", main.car_sign[0]);
                editor.apply();
            }
        });
        btn_3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (main.car_sign[0]!=3){
                    main.car_sign[0]=3;
                    btn_1.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_2.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_3.setBackgroundColor(ContextCompat.getColor(context, R.color.red));
                }
                else {
                    main.car_sign[0]=0;
                    btn_1.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_2.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_3.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                }
                editor.putInt("car_sign0", main.car_sign[0]);
                editor.apply();
            }
        });

        btn_4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (main.car_sign[1]!=1){
                    main.car_sign[1]=1;
                    btn_4.setBackgroundColor(ContextCompat.getColor(context, R.color.red));
                    btn_5.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_6.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                }
                else {
                    main.car_sign[1]=0;
                    btn_4.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_5.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_6.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                }
                editor.putInt("car_sign1", main.car_sign[1]);
                editor.apply();
            }
        });
        btn_5.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (main.car_sign[1]!=2){
                    main.car_sign[1]=2;
                    btn_4.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_5.setBackgroundColor(ContextCompat.getColor(context, R.color.red));
                    btn_6.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                }
                else {
                    main.car_sign[1]=0;
                    btn_4.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_5.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_6.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                }
                editor.putInt("car_sign1", main.car_sign[1]);
                editor.apply();
            }
        });
        btn_6.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (main.car_sign[1]!=3){
                    main.car_sign[1]=3;
                    btn_4.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_5.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_6.setBackgroundColor(ContextCompat.getColor(context, R.color.red));
                }
                else {
                    main.car_sign[1]=0;
                    btn_4.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_5.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_6.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                }
                editor.putInt("car_sign1", main.car_sign[1]);
                editor.apply();
            }
        });

        btn_7.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (main.car_sign[2]!=1){
                    main.car_sign[2]=1;
                    btn_7.setBackgroundColor(ContextCompat.getColor(context, R.color.red));
                    btn_8.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_9.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                }
                else {
                    main.car_sign[2]=0;
                    btn_7.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_8.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_9.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                }
                editor.putInt("car_sign2", main.car_sign[2]);
                editor.apply();
            }
        });
        btn_8.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (main.car_sign[2]!=2){
                    main.car_sign[2]=2;
                    btn_7.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_8.setBackgroundColor(ContextCompat.getColor(context, R.color.red));
                    btn_9.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                }
                else {
                    main.car_sign[2]=0;
                    btn_7.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_8.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_9.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                }
                editor.putInt("car_sign2", main.car_sign[2]);
                editor.apply();
            }
        });
        btn_9.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (main.car_sign[2]!=3){
                    main.car_sign[2]=3;
                    btn_7.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_8.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_9.setBackgroundColor(ContextCompat.getColor(context, R.color.red));
                }
                else {
                    main.car_sign[2]=0;
                    btn_7.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_8.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_9.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                }
                editor.putInt("car_sign2", main.car_sign[2]);
                editor.apply();
            }
        });

        btn_10.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (main.work_sign!=1){
                    main.work_sign=1;
                    btn_10.setBackgroundColor(ContextCompat.getColor(context, R.color.red));
                    btn_11.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                }
                else {
                    main.work_sign=0;
                    btn_10.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_11.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                }
                editor.putInt("work_sign", main.work_sign);
                editor.apply();
            }
        });
        btn_11.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (main.work_sign!=2){
                    main.work_sign=2;
                    btn_10.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_11.setBackgroundColor(ContextCompat.getColor(context, R.color.red));
                }
                else {
                    main.work_sign=0;
                    btn_10.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                    btn_11.setBackgroundColor(ContextCompat.getColor(context, R.color.skyblue));
                }
                editor.putInt("work_sign", main.work_sign);
                editor.apply();
            }
        });
        btn_0.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (socket_flag==2) {
                    send_data_flag = true;
                }

            }
        });


        //开启主逻辑线程
        if(!Main_Runnable_flag) {
            Main_Runnable_flag = true;
            ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
            scheduler.scheduleWithFixedDelay(Main_Runnable, 0, 1, TimeUnit.MILLISECONDS);
        }

    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        Init();

    }

    Runnable Main_Runnable  = () -> {
        if (socket_flag > 0) {
            if (socket != null) {
                if (!socket.isClosed()) {
                    if (socket.isConnected()) {
                        try {
                            DataInputStream input = new DataInputStream(socket.getInputStream());
                            if (input.available() > 0) {// 检查是否有可用的数据
                                byte[] buffer = new byte[input.available()];
                                input.readFully(buffer);// 读取字节数据到buffer数组中
                                if (buffer.length == 12 && buffer[0] == (byte)0xFE && buffer[1] == (byte)0xEF)
                                {
                                    for (ping_data item : ping_data_list) {
                                        if (item.data == buffer[2])
                                        {
                                            long time = SystemClock.uptimeMillis() - item.time;
                                            main.tv_ping_text = time + "ms";
                                            if (time<200)main.tv_ping_text_Shadow_color = R.color.green;
                                            else main.tv_ping_text_Shadow_color = R.color.crimson;
                                            runOnUiThread(() -> {
                                                tv_ping.setText(main.tv_ping_text);
                                                tv_ping.setShadowLayer(5, 5, 5, ContextCompat.getColor(this, main.tv_ping_text_Shadow_color));
                                            });
                                            ping_data_list.clear();

                                            if (socket_flag == 1) {
                                                socket_flag = 2;
                                                main.tv_connect_text = "已连接";
                                                main.tv_connect_text_Shadow_color = R.color.green;
                                                runOnUiThread(() -> {
                                                    tv_connect.setText(main.tv_connect_text);
                                                    tv_connect.setShadowLayer(5, 5, 5, ContextCompat.getColor(this, main.tv_connect_text_Shadow_color));
                                                });
                                            }
                                            break;
                                        }
                                    }
                                    if (buffer[3] == main.car_sign[0]&& buffer[4] == main.car_sign[1]&&
                                            buffer[5] == main.car_sign[2]&& buffer[6] == main.work_sign){
                                        send_data_flag = false;
                                        main.tv_data_match_text_Shadow_color  = R.color.green;
                                        runOnUiThread(() -> {
                                            tv_data_match.setShadowLayer(5, 5, 5, ContextCompat.getColor(this, main.tv_data_match_text_Shadow_color));
                                        });
                                    }
                                    else {
                                        main.tv_data_match_text_Shadow_color  = R.color.crimson;
                                        runOnUiThread(() -> {
                                            tv_data_match.setShadowLayer(5, 5, 5, ContextCompat.getColor(this, main.tv_data_match_text_Shadow_color));
                                        });
                                    }
                                }
                            }
                        }
                        catch (IOException ignored) {}
                        if (Main_Runnable_count % 500 == 0)
                        {
                            new Thread(() -> {
                                OutputStream outputStream;
                                try {
                                    outputStream = socket.getOutputStream();
                                    ping_data_list.add(new ping_data((byte)ping_data_list.size(),SystemClock.uptimeMillis()));
                                    byte[] charArray = {(byte) 0xFE, (byte)0xEF, ping_data_list.get(ping_data_list.size()-1).data};
                                    outputStream.write(charArray);
                                    outputStream.flush();
                                    timeout = 0;
                                } catch (IOException e) {
                                    timeout = timeout + 1;
                                    Log.e(TAG, "addr连接超时" + timeout);
                                    if (timeout > 2) {
                                        try {socket.close();} catch (IOException ignored1) {}
                                        socket_flag = 0;

                                        main.tv_connect_text = "未连接";
                                        main.tv_connect_text_Shadow_color  = R.color.crimson;
                                        main.tv_ping_text = "500ms";
                                        main.tv_ping_text_Shadow_color = R.color.crimson;
                                        runOnUiThread(() -> {
                                            tv_connect.setText(main.tv_connect_text);
                                            tv_connect.setShadowLayer(5, 5, 5, ContextCompat.getColor(this, main.tv_connect_text_Shadow_color));
                                            tv_ping.setText(main.tv_ping_text);
                                            tv_ping.setShadowLayer(5, 5, 5, ContextCompat.getColor(this, main.tv_ping_text_Shadow_color));
                                        });
                                    }
                                }
                            }).start();
                            if (send_data_flag && socket_flag==2) {
                                new Thread(() -> {
                                    OutputStream outputStream;
                                    try {
                                        outputStream = socket.getOutputStream();
                                        ping_data_list.add(new ping_data((byte)ping_data_list.size(),SystemClock.uptimeMillis()));
                                        byte[] charArray =
                                                {(byte) 0xFA, (byte)0xAF,
                                                main.car_sign[0], main.car_sign[1], main.car_sign[2],
                                                        main.work_sign};
                                        outputStream.write(charArray);
                                        outputStream.flush();
                                    } catch (IOException ignored) { }
                                }).start();
                            }
                        }
                    }
                }
            }
        }
        else {
            if (Main_Runnable_count % 1000 == 0)
            {
                new Thread(()-> {
                    main.tv_connect_text = "连接中";
                    main.tv_connect_text_Shadow_color = R.color.skyblue;
                    runOnUiThread(() -> {
                        tv_connect.setText(main.tv_connect_text);
                        tv_connect.setShadowLayer(5, 5, 5, ContextCompat.getColor(this, main.tv_connect_text_Shadow_color));
                    });
                    try {
                        socket = new Socket();
                        socket.connect(new InetSocketAddress(main.et_ip_text, Integer.parseInt(main.et_port_text)) ,500);
                        //连接成功
                        socket_flag = 1;


                    }
                    catch (IOException exception) {
                        Log.d("my debug", exception.toString());

                        main.tv_connect_text = "未连接";
                        main.tv_connect_text_Shadow_color  = R.color.crimson;
                        runOnUiThread(() -> {
                            tv_connect.setText(main.tv_connect_text);
                            tv_connect.setShadowLayer(5, 5, 5, ContextCompat.getColor(this, main.tv_connect_text_Shadow_color));
                        });
                        try {socket.close();} catch (IOException ignored1) {}
                    }
                }).start();
            }
        }
        Main_Runnable_count = Main_Runnable_count + 1;
        if (Main_Runnable_count == 600000)Main_Runnable_count=0;
    };
}